package Project2;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

/*
 * Project 2 (OBJ)
 * Tony Burks
 * 10/4/2009
 *
 * Purpose:
 * =============================================================================================
 * A bank has account owners, each of them may have one or more bank accounts, 
 * such as savings accounts, checking accounts, and business accounts. 
 * Each account has the following information stored as private data: such as name,  
 * account_number, and balance.  At the end of each month, the bank issues a statement 
 * for each bank account containing the following information: name, SSN, account_number,
 *  phone_number, open balance, and close balance. The close balance is the open balance
 *   plus the interest calculated based on the type of the account. To simplify your task,
 *    you can assume that there was no transaction in the past month. 
 *    With a polymorphic method, the interest of each account is calculated differently:
 *    1.	No interest for business accounts
 *    2.	2.5% interest for each checking account
 *    3.	4% for each saving account if the balance  < $5000
 *    5% otherwise
 * ==============================================================================================
 * 
 * Input File is: InputFile.txt
 */

/*
 * This is the Main Driver Class of the application
 * This class handles input, output and calling for account calculations
 */
public class IOClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//Create the Account Array list
		ArrayList<Account> Acts = new ArrayList<Account>();
		System.out.println("Start");
		//Fill the Account Array with data
		Acts = ReadData("InputFile.txt");
		System.out.println("Read File");
		//Call the interest calculations
		Acts = CalcNewBalance(Acts);
		System.out.println("Calulations Complete");
		//Output the Data
		OutputData("OutputFile.txt", Acts);
		System.out.println("Done");

	}
	
	/*
	 * ReadFile Takes in a FileName
	 * This function takes the contents of a file and puts it into a String
	 */
	public static String ReadFile(String FileName)
	{
		try
		{
			
	      BufferedReader BR =  new BufferedReader(new FileReader(FileName));
		    
			String FileString = "";
			String strLine = "";

			while ((strLine = BR.readLine()) != null)   {
			      // Print the content on the console
				FileString = FileString + strLine ;
			    }
			
			return FileString;

		}
		catch(Exception E)
		{
		System.out.println(E.getMessage());	
		return "";
		}
		
	}
	
	/*
	 * This function handles reading data from the input file
	 */
	public static ArrayList<Account> ReadData(String FileName)
	{
		try
		{
//		String EndOfLine = System.getProperty("line.separator");
		
		String AccName = "";
		String AccNum = "";
		String AccPhone = "";
		String AccSSN = "";
		double AccBalance = 0;
		String AccType = "";
		Account NewAcc = null;
		
		ArrayList<Account> Acts = new ArrayList<Account>();

		// gets the file as a string 
		String AccString = ReadFile(FileName);
		
		char CurChr;
		ArrayList<String> Words = new ArrayList<String>();
		int WordCount = -1;
		boolean NextWord = true;
		for (int i = 0; i < AccString.length(); i++)
		{
			//Read Next Character
			CurChr = AccString.charAt(i);
			//If Character is Not EOL then Check for Space
			if (CurChr != '|')
			{
				// If Space then Next String = True
				if (CurChr == ' ' || CurChr == '\t')
				{
					NextWord = true;
				}
				else
				{
					/// If NextString true Increment String Count by 1
					if (NextWord)
					{
						NextWord = false;
						WordCount += 1;
						Words.add( "");
					}
					Words.set(WordCount, Words.get(WordCount).toString() + CurChr);
				}
			}
			else
			{
			/// Assign Words from Array to Values based on known Assignments 	
			AccName = Words.get(0);
			AccNum = Words.get(1);
			AccPhone = Words.get(2);
			AccSSN = Words.get(3);
			AccBalance = Double.parseDouble( Words.get(4))	;
			AccType = Words.get(5);


			/*
			 * 
			 * Add New Account Code
			 */
			if (AccType.equals("B"))
			{
				NewAcc = new BusinessAccount(AccName, AccNum, AccPhone, AccSSN, AccBalance);
			}
			if (AccType.equals("C"))
			{
				NewAcc = new CheckingAccount(AccName, AccNum, AccPhone, AccSSN, AccBalance);
			}
			if (AccType.equals("S") )
			{
				NewAcc = new SavingsAccount(AccName, AccNum, AccPhone, AccSSN, AccBalance);
			}
			Acts.add(NewAcc);
			/*
 			* Reset All Read Values		
 			*/
			Words = new ArrayList<String>();
			WordCount = -1;
			NextWord = true;
			}
		}
		
		
		
	

		return Acts;
		}
		catch(Exception E)
		{
			System.out.println(E.getMessage());	
		}
		return null;	
	}
	
	/*
	 * This Function handles writing the Account Data to the output screen
	 */
	public static void OutputData(String FileName, ArrayList<Account> Acts)
	{
		System.out.print("Name      ");
		System.out.print("Account   ");
		System.out.print("Phone     ");
		System.out.print("SSN            ");
		System.out.print("Open Balance   ");
		System.out.print("Close Balance  ");
		System.out.print("Interest  ");
		System.out.println("Account Type   ");
		
		for (int i = 0; i < Acts.size(); i++)
		{
			System.out.print(Acts.get(i).Name );
			Formating(10, Acts.get(i).Name.length());
			System.out.print(Acts.get(i).Account  );
			Formating(10, Acts.get(i).Account.length());
			System.out.print(Acts.get(i).Phone  );
			Formating(10, Acts.get(i).Phone.length());
			System.out.print(Acts.get(i).SSN  );
			Formating(15, Acts.get(i).SSN.length());
			System.out.print(Acts.get(i).BeginBalance  );
			Formating(15, String.valueOf(Acts.get(i).BeginBalance).length());
			System.out.print(Acts.get(i).NewBalance  );
			Formating(15, String.valueOf(Acts.get(i).NewBalance).length());
			System.out.print(Acts.get(i).InterestGained );
			Formating(10, String.valueOf(Acts.get(i).InterestGained).length());
			System.out.println(Acts.get(i).Type );			
		}
	}
	
	/*
	 * This function is used to format the output
	 * It takes the desired length of a field and length of the data and outputs any needed white spaces
	 */
	public static void Formating(int DesiredLength, int StringLength)
	{
		for (int i = StringLength; i < DesiredLength; i++)
		{
			System.out.print(" ");
		}
	}

	/*
	 * This function calls each account to Calculate its interest
	 */
	public static ArrayList<Account> CalcNewBalance(ArrayList<Account> Acts)
	{

		//This loop cycles through all the accounts
		for (int i = 0; i < Acts.size(); i++)
			{
		//		System.out.println(Acts.get(i).BeginBalance);
				//This call makes the account calculate its new balance and adds that balance to
				//the new balance Var in the account class
				Acts.get(i).CalcInt();
	//			System.out.println(Acts.get(i).NewBalance);
			}
		return Acts;	
	}

}
